﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Security.Permissions;

namespace GLSimulationControl
{
    public partial class GeometryMillingPreview : UserControl
    {
        private PinnedObject<IntPtr> _hdc;
        private PinnedObject<IntPtr> _hglrc;
        private PinnedObject<IntPtr> _library;

        internal IntPtr HDC
        {
            get
            {
                return this._hdc.ManangedObject;
            }
        }

        internal IntPtr HGLRC
        {
            get
            {
                return this._hglrc.ManangedObject;
            }
        }

        #region GraphicsWindowsFunctions
        [DllImport( "user32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true )]
        public static extern IntPtr GetDC(IntPtr hWnd);

        [DllImport( "gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true )]
        public static extern int ChoosePixelFormat(IntPtr hdc, [In] ref PIXELFORMATDESCRIPTOR ppfd);

        [DllImport( "gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true )]
        public static extern bool SetPixelFormat(IntPtr hdc, int iPixelFormat, ref PIXELFORMATDESCRIPTOR ppfd);

        [DllImport( "opengl32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true )]
        public static extern IntPtr wglCreateContext(IntPtr hDC);

        [DllImport( "user32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true )]
        static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);

        [DllImport( "glew32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true )]
        static extern int glewInit();

        [DllImport( "opengl32.dll", EntryPoint = "glGetString", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true )]
        static extern IntPtr _glGetString(StringName name);
        public static string glGetString(StringName name)
        {
            return Marshal.PtrToStringAnsi( _glGetString( name ) );
        }

        [DllImport( "gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true )]
        public static extern bool SwapBuffers(IntPtr hdc);
        #endregion

        #region PathGenerationDLL
        [DllImport( "3CSimulatorLib.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true )]
        public static extern void GenerateAndSavePathFile([MarshalAs( UnmanagedType.LPStr )] string fileName);
        #endregion

        [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode )]
        public GeometryMillingPreview()
        {
            InitializeComponent();
            this.SetStyle( ControlStyles.EnableNotifyMessage, true );
            if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)
                return;
            try
            {
                glGetString( 0 );
                this._library = new PinnedObject<IntPtr>();
                this._hdc = new PinnedObject<IntPtr>();
                this._hglrc = new PinnedObject<IntPtr>();
                this.Func_Init( this.Handle );
               // int err = glewInit();
                //InitGL( this.HDC, this.HGLRC );
            }
            catch (Exception e)
            {
                MessageBox.Show( e.Message );
            }
        }

        public void Func_Init(IntPtr hwnd)
        {
            this._hdc.ManangedObject = GetDC( hwnd );
            var pixelFormatDescriptor = new PIXELFORMATDESCRIPTOR();
            pixelFormatDescriptor.Init();

            var pixelFormat = ChoosePixelFormat( _hdc.ManangedObject, ref pixelFormatDescriptor );
            if (!SetPixelFormat( _hdc.ManangedObject, pixelFormat, ref pixelFormatDescriptor ))
                throw new Win32Exception( Marshal.GetLastWin32Error() );
            if ((this._hglrc.ManangedObject = wglCreateContext( _hdc.ManangedObject )) == IntPtr.Zero)
                throw new Win32Exception( Marshal.GetLastWin32Error() );
        }

        /*
        [System.Security.Permissions.PermissionSet( System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust" )]
        protected override void WndProc(ref Message m)
        {
           // if (LicenseManager.UsageMode == LicenseUsageMode.Designtime || this.DesignMode)
           //     return;

            if (m.Msg == 0x14)//filter out the WM_ERASEBACKGROUND
            {
                return;
            }
            base.WndProc( ref m );
        }*/
    }
}
